import type {
  Settings as LayoutSettings,
  BasicLayoutProps,
  MenuDataItem,
} from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import { history, dynamic } from 'umi';
import RightContent from '@/components/RightContent';
// import Footer from '@/components/Footer';
import { currentUser, getToken, removeToken } from './services/user';
import { getMenu, getRoutes } from './services/sysInfo';
import { getBankName, getAppName } from './utils/common';
import { loadSysName } from '@/services/sysInfo';
import defaultSettings from '../config/defaultSettings';
import { notification } from 'antd';
// @ts-ignore
import type { RequestOptionsInit } from 'umi';
import type { RequestConfig } from 'umi';
import type { ResponseError } from 'umi-request';

import _ from 'lodash';

let authRoutes: API.Route[] = [];

function parseRoute(ar: API.Route) {
  if (_.isEmpty(ar.component)) {
    return undefined;
  }
  const routePath = ar.component;
  ar.component = dynamic({
    loader: async function () {
      return await import(`./pages/${routePath}.tsx`);
    },
  });
  return ar;
}
export function patchRoutes(routes: any) {
  if (authRoutes === undefined) {
    return routes;
  }
  authRoutes.forEach((item) => {
    const pr = parseRoute(item);
    if (pr !== undefined) {
      routes.routes[0].routes.push(pr);
    }
  });
  routes.routes[0].routes.push({
    component: dynamic({
      loader: async function () {
        return await import('./pages/404');
      },
    }),
  });
  return routes;
}
export function render(oldRoutes: any) {
  getRoutes()
    .then(function (data) {
      authRoutes = data;
      oldRoutes();
    })
    .catch(function (ex) {
      console.log('请求出错', ex);
    });
}

const loginPath = '/user/login';
let isRun = false;
/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
  loading: <PageLoading />,
};
/**
 * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 * */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  user?: API.UserInfo;
  sys?: API.SysInfo;
  loading?: boolean;
  appNo?: string;
  fetchSysInfo?: () => Promise<
    | { userInfo: API.UserInfo | undefined; sysInfo: API.SysInfo | undefined; appNo: string }
    | undefined
  >;
}> {
  const fetchSysInfo = async () => {
    const name = await loadSysName();
    let userInfo: API.UserInfo | undefined = undefined;
    let sysInfo: API.SysInfo | undefined = undefined;
    try {
      userInfo = await currentUser();
      sysInfo = await getMenu();
    } catch (error) {
      history.push(loginPath);
    } finally {
      return { userInfo, sysInfo, appNo: name };
    }
  };
  const info = await fetchSysInfo();
  const sysName = getBankName(info.appNo, false) + getAppName(info.appNo);
  const token = getToken();
  // 如果是登录页面，不执行
  if (history.location.pathname !== loginPath && token) {
    return {
      fetchSysInfo,
      user: info?.userInfo,
      sys: info?.sysInfo,
      appNo: info.appNo,
      settings: { ...defaultSettings, title: sysName },
    };
  }
  return {
    fetchSysInfo,
    appNo: info.appNo,
    settings: { ...defaultSettings, title: sysName },
  };
}
export const layout = ({
  initialState,
}: {
  initialState: {
    settings?: LayoutSettings;
    user?: API.UserInfo;
    sys?: API.SysInfo;
  };
}): BasicLayoutProps => {
  //add:使用lodash 判断路由是否空
  const routes = _.isEmpty(initialState?.sys?.menuDatas)
    ? { routes: [] }
    : initialState?.sys?.menuDatas;
  return {
    logo: false,
    menuDataRender: () => routes as MenuDataItem[],
    rightContentRender: () => <RightContent />,
    disableContentMargin: true,
    footerRender: () => null,
    onMenuHeaderClick: () => history.push('/'),
    onPageChange: () => {
      // 如果没有登录，重定向到 login
      if (isRun) {
        isRun = false;
      } else if (_.isEmpty(initialState?.user) && history.location.pathname !== '/user/login') {
        history.push('/user/login');
      }
    },
    iconfontUrl: undefined,
    menuHeaderRender: undefined,
    ...initialState?.settings,
  };
};

/** 异常处理程序
 * @see https://beta-pro.ant.design/docs/request-cn
 */ const errorHandler = async (error: ResponseError) => {
  // 两者只会存在一个  response：接口没响应的返回  data：接口响应成功返回的业务数据
  const { response, data } = error;

  let errorText;

  if (response && response.status) {
    const { status, url } = response;
    if (status === 403) {
      isRun = true;
      history.push('/403');
      return;
    } else if (status === 401) {
      history.push('/user/login');
      return;
    }
    errorText = data.message;
    if (errorText === undefined) {
      const errmsg = await data.text();
      errorText = JSON.parse(errmsg).message;
    }
    const err_msg = errorText as string;
    if (err_msg.endsWith('jwt')) {
      return;
    }
    notification.error({
      message: `请求错误 ${status}: ${url}` || '您的网络发生异常，无法连接服务器',
      description: err_msg || '网络异常',
    });
  }

  if (data && data.code) {
    console.log('errorHandler data ', data);
    errorText = data.msg;
    // token无效
    if (data.code === 401) {
      // 移除token
      removeToken();
      // 跳转到登录页面
      history.push('/login');
    }
  }

  throw errorText;
};

// 将接口的返回映射为统一的接口规范  该配置只是用于错误处理，不会影响最终传递给页面的数据格式 https://umijs.org/plugins/plugin-request
const errorConfig = {
  adaptor: (resData: any) => {
    return {
      ...resData,
    };
  },
};

// 新增自动添加AccessToken的请求前拦截器
const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
  const authHeader = { Authorization: getToken() };
  return {
    url: `${url}`,
    options: { ...options, interceptors: true, headers: authHeader },
  };
};

// https://umijs.org/zh-CN/plugins/plugin-request
export const request: RequestConfig = {
  errorHandler,
  errorConfig,
  requestInterceptors: [authHeaderInterceptor],
};
